/**
 * @author Kristian Mandrup
 * @date June 10, 2009
 * @version 0.1
 * 
 * m3gen :: AttributesBuilder
 * m3gen :: DataBuilder
 * m3gen :: StateBuilder
 * m3gen :: ChildrenBuilder 
 *  
 * - Builders for building each of the values for the keys of a jsTreeNode
 * 
 * 
 * AttributesBuilder:: Usage 
 * -------------------------
 * var my_AttributesBuilder = new AttributesBuilder();
 * jsTreeNode.attributes = my_AttributesBuilder.build(nodeObj);
 * 
 * DataBuilder:: Usage 
 * -------------------------
 * var my_DataBuilder = new DataBuilder();
 * jsTreeNode.data = my_DataBuilder.build(nodeObj);
 *
 * StateBuilder:: Usage 
 * -------------------------
 * var my_StateBuilder = new StateBuilder();
 * jsTreeNode.state = my_StateBuilder.build(nodeObj);
 * 
 * ChildrenBuilder:: Usage 
 * -------------------------
 * var my_ChildrenBuilder = new ChildrenBuilder();
 * jsTreeNode.children = my_ChildrenBuilder.build(nodeObj);
 * 
 * MetaDataBuilder:: Usage 
 * -------------------------
 * var my_MetaDataBuilder = new MetaDataBuilder();
 * jsTreeNode.mdata = my_MetaDataBuilder.build(nodeObj);
 * 
 * 
 */

// setup namespace: jsTreeNode
m3gen.jsTreeNode = {};

 /**
 * AttributesBuilder constructor function
 */
m3gen.jsTreeNode.AttributesBuilder = function(createOptions) {
	// call Builder superclass initializer 
	this.init(createOptions);
}

m3gen.jsTreeNode.AttributesBuilder.prototype.init = function(createOptions){
	this.uber('init', createOptions);		
}

// inherit from Builder
m3gen.jsTreeNode.AttributesBuilder.inherits(m3gen.Base);	


/**
 * Build the attributes object for a jsTree node
 * Special keys for jsTree
 * - id
 * - rel (relation) fx "root" or "folder"
 * @param {Object} nodeObj
 */
m3gen.jsTreeNode.AttributesBuilder.prototype.execute = function (nodeObj) {
	var attributes = {};
	// set id
	var id = this.getIdFromNodeObj(nodeObj);
	if (this.getUseUniqueId()) {
		id = this.getUniqueIdFromNodeObj(nodeObj);		
	} 
	attributes.id = id;
	
	// relation
	if (nodeObj.relation)
		attributes.rel = nodeObj.relation;

	if (nodeObj['class'])
		attributes['class']= nodeObj['class'];

	var nodeObjAttribs = nodeObj.attributes || {};
	for (var attributeKey in nodeObjAttribs) {
		if (attributeKey != 'id' && attributeKey != 'relation') {
			attributes[attributeKey] = nodeObjAttribs[attributeKey];
		}
	}	
	return attributes;
}

/**
 * DataBuilder constructor function
 */
m3gen.jsTreeNode.MetaDataBuilder = function(createOptions) {
	// call Builder superclass initializer 
	this.init(createOptions);
}

m3gen.jsTreeNode.MetaDataBuilder.prototype.init = function(createOptions){
	this.uber('init', createOptions);
}

// inherit from Builder
m3gen.jsTreeNode.MetaDataBuilder.inherits(m3gen.Base);	


/**
 * Build the mdata object for a jsTree node
 * @param {Object} nodeObj
 * 
 * The nodeObj can expectdd
 * 
 * The metadata could be something like the following:
 * mdata: "{ draggable : false, max_children : 1, max_depth : 1 }"
 * 
 */
m3gen.jsTreeNode.MetaDataBuilder.prototype.execute = function (nodeObj) {
	// convert json obj to string
	var metaData = nodeObj.metaData;
	var mdata = null;
	if (metaData) {
		mdata = dojo.toJson().toString();
	}
	return mdata;
}

/**
 * DataBuilder constructor function
 */
m3gen.jsTreeNode.DataBuilder = function(createOptions) {
	this.init(createOptions);
}

m3gen.jsTreeNode.DataBuilder.prototype.init = function(createOptions){
	// call Builder superclass initializer 
	this.uber('init', createOptions);		
}


// inherit from Builder
m3gen.jsTreeNode.DataBuilder.inherits(m3gen.Base);	


/**
 * Expects a languages model in nodeObj like this:
 * languages: {
 * 	'dk': {title: 'min titel', icon: 'danish/folder.png', attributes: {...}},
 *  'en': {title: 'my titel', icon: 'english/folder.png', attributes: {...}},  
 * }
 * @param {Object} nodeObj
 */
m3gen.jsTreeNode.DataBuilder.prototype.execute = function(nodeObj){
	var data = {};
	// is languageMode on?
	if (this.getLanguageModeOn()) {
		var languages = nodeObj.languageData;
		for (var languageKey in languages) {
			var langDataItem = languages[languageKey];
			if (this.isValidObj(langDataItem))
				data[languageKey] = langDataItem;
		}
	} else {
		// use basic data if not languageMode
		data = nodeObj.data;
	}
	return data;
}

/**
 * StateBuilder constructor function
 */
m3gen.jsTreeNode.StateBuilder = function(createOptions) {
	this.init(createOptions);
}

m3gen.jsTreeNode.StateBuilder.prototype.init = function(createOptions){
	// call Builder superclass initializer 
	this.uber('init', createOptions);
}


// inherit from Builder
m3gen.jsTreeNode.StateBuilder.inherits(m3gen.Base);	


m3gen.jsTreeNode.StateBuilder.prototype.execute = function (nodeObj) {
	return nodeObj.state;
}

/**
 * ChildrenBuilder constructor function
 */
m3gen.jsTreeNode.ChildrenBuilder = function(createOptions) {
	this.init(createOptions);
}

m3gen.jsTreeNode.ChildrenBuilder.prototype.init = function(createOptions){
	// call Builder superclass initializer 
	this.uber('init', createOptions);		
}

// inherit from Builder
m3gen.jsTreeNode.ChildrenBuilder.inherits(m3gen.Base);	

/**
 * Build an array of jsTreeNodes (child nodes) to be set on a jsTreeNode.children 
 * 
 * @param {Object} nodeObj
 * 
 * nodeObj = {
 * 	id: "..",
 *  attributes: {...}, 		(optional)
 *  state: " ", 			(optional)
 *  languageData: {... } 	(optional)
 * }
 */
m3gen.jsTreeNode.ChildrenBuilder.prototype.execute = function (nodeObj) {	
	var nodeObjChildren = nodeObj.children;
	
	var jsTreeNode_children = [];
	
	if (this.isNotEmptyArray(nodeObjChildren)) {
		// iterate each nodeObj in nodeObjChildren 
		// create branch for each and add to children result list
		var that = this;
		nodeObjChildren.forEach(function(childNodeObj){
			if (!that.isEmptyBranchNodeObj(childNodeObj) && !that.getIncludeEmptyBranchesModeOn()) {
				var jsTreeChildNode = that.getJsTreeNodeBuilderInstance().execute(childNodeObj);
				
				// jsTreeBranch_children can either be a single branchNodeObj with children 
				// or a branchless list of children
				if (that.isValidJsTreeNode(jsTreeChildNode, that)) 
					jsTreeNode_children.push(jsTreeChildNode);
			}
		});
	}
	return jsTreeNode_children;
}
